﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using LiveSequence.Common.Domain;
using LiveSequence.Suite.Domain;
using LiveSequence.Suite.Interfaces;

namespace LiveSequence.Suite.Views
{
  internal partial class CallTreeView : UserControl
  {
    private ISDIController _projectController;
    public CallTreeView(ISDIController projectController)
    {
      InitializeComponent();
      InitializeComponentEx();
      _projectController = projectController;
      _projectController.SelectedDiagramChanged += new EventHandler(_projectController_SelectedDiagramChanged);
    }

    private void InitializeComponentEx()
    {
      _methodCalltreeView.CheckBoxes = true;
      _methodCalltreeView.AfterCheck += new TreeViewEventHandler(_methodCalltreeView_AfterCheck);
      _methodCalltreeView.AfterSelect += new TreeViewEventHandler(_methodCalltreeView_AfterSelect);
    }

    void _methodCalltreeView_AfterSelect(object sender, TreeViewEventArgs e)
    {
      MethodCallInfoTreeNode methodNode = e.Node as MethodCallInfoTreeNode;
      if (methodNode != null)
      {
        PropertyViewManager.Instance.SelectedObject = methodNode.Item;
      }
    }

    void _methodCalltreeView_AfterCheck(object sender, TreeViewEventArgs e)
    {
      _methodCalltreeView.CanRaiseAfterCheckEvent = false;

      MethodCallInfoTreeNode methodNode = e.Node as MethodCallInfoTreeNode;
      if (methodNode != null)
      {
        methodNode.Item.Visible = e.Node.Checked;
      }

      CheckChildTreeNodes(e.Node, e.Node.Checked);

      _methodCalltreeView.CanRaiseAfterCheckEvent = true;
    }

    private void CheckChildTreeNodes(TreeNode treeNode, bool bChecked)
    {
      foreach (TreeNode child in treeNode.Nodes)
      {
        MethodCallInfoTreeNode methodNode = child as MethodCallInfoTreeNode;
        if (methodNode != null)
        {
          methodNode.Item.Visible = bChecked;
        }
        child.Checked = bChecked;
        CheckChildTreeNodes(child, bChecked);

      }

    }


    void _projectController_SelectedDiagramChanged(object sender, EventArgs e)
    {
      UpdateView();
    }

    private void UpdateView()
    {
      LSMethodCallDiagram diagram = _projectController.SelectedDiagram;
      populateSequenceDataTreeView(diagram.SequenceData);  
    }

    private void populateSequenceDataTreeView(SequenceData data)
    {
      _methodCalltreeView.Nodes.Clear();
      List<MethodCallInfo> listMethods = data.GetMethodList();
      int iIndex = 0;

      TreeNode node = new TreeNode("METHOD");

      _methodCalltreeView.CanRaiseAfterCheckEvent = false;

      _methodCalltreeView.Nodes.Add(node);
      if (listMethods.Count > 0)
      {
        MethodCallInfo methodCallInfo = listMethods[iIndex];

        populateSequenceDataSubTreeView(methodCallInfo.MethodName,
                                        methodCallInfo.TypeName,
                                        node,
                                        ref iIndex,
                                        listMethods);
      }

      _methodCalltreeView.CanRaiseAfterCheckEvent = true;

      node.ExpandAll();
    }



    private void populateSequenceDataSubTreeView(string strMethodCall,
                                                 string strTypeCall,
                                                 TreeNode nodeCaller,
                                                 ref int iIndex,
                                                 List<MethodCallInfo> listMethods)
    {
      while (iIndex < listMethods.Count)
      {
        MethodCallInfo methodCallInfo = listMethods[iIndex];

        if ((methodCallInfo.MethodName == strMethodCall) &&
          (methodCallInfo.TypeName == strTypeCall))
        {
          MethodCallInfoTreeNode child = new MethodCallInfoTreeNode(methodCallInfo);
          child.Checked = methodCallInfo.Visible;
          nodeCaller.Nodes.Add(child);
          iIndex++;
          populateSequenceDataSubTreeView(methodCallInfo.MethodCallName,
                                          methodCallInfo.MethodCallType,
                                          child,
                                           ref iIndex,
                                          listMethods);

        }
        else
        {
          break;
        }
      }

    }


  }
}
